package com.project.bookstore.category.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.project.bookstore.cache.repo.ICategoryCacheRepository;
import com.project.bookstore.category.domain.Category;
import com.project.bookstore.category.pojo.CategoryIndexDO;
import com.project.bookstore.category.pojo.CategoryIndexVO;
import com.project.bookstore.category.pojo.CategoryRelatedVO;
import com.project.bookstore.category.service.CategoryService;
import com.project.bookstore.category.mapper.CategoryMapper;
import com.project.bookstore.common.CommonResult;
import com.project.bookstore.exception.ServiceInternalException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 12603
 * @description 针对表【t_category(类别)】的数据库操作Service实现
 * @createDate 2022-05-13 13:37:16
 */
@Service
@Slf4j
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category>
        implements CategoryService {

    @Autowired
    private CategoryMapper mapper;

    @Autowired
    private ICategoryCacheRepository categoryCacheRepository;

    @Override
    public CommonResult<List<CategoryIndexVO>> getCategoryForIndex() {
        List<CategoryIndexDO> categoryIndexDOS = categoryCacheRepository.getCategoryIndexVOS();
        log.debug("redis 中的数据【{}】", categoryIndexDOS);
        if (categoryIndexDOS == null || categoryIndexDOS.size() == 0) {
            log.debug("缓存中没有首页类别数据，开始从数据库查询");
            categoryIndexDOS = mapper.listForIndex();
            if (categoryIndexDOS == null) {
                log.warn("未知原因，从数据库中获取首页类别数据异常");
                throw new ServiceInternalException();
            }
            log.debug("将数据缓存到redis");
            categoryCacheRepository.setCategories(categoryIndexDOS);
        }
        List<CategoryIndexVO> categoryIndexVOS = categoryDOTreeToVO(categoryIndexDOS);
        log.debug("类别层级转换完成：【{}】", categoryIndexVOS);
        return CommonResult.ok(categoryIndexVOS);
    }

    @Override
    public Long[] getRelatedClassifyIds(Long parentId) {
        return mapper.listIdByParentId(parentId);
    }

    @Override
    public CommonResult<List<CategoryRelatedVO>> getRelatedClassify(Long classifyId) {
        //通过 parentId 找到所有子类别名
        List<CategoryRelatedVO> relatedVOS = mapper.listChildrenByParentId(classifyId);
        if (relatedVOS==null||relatedVOS.size()==0){
            log.warn("详情页根据类别ID【{}】获取相关ID时查到数据为空",classifyId);
            throw new ServiceInternalException();
        }
        relatedVOS.forEach(e->e.setHref("category_"+e.getId()));
        return CommonResult.ok(relatedVOS);
    }

    /**
     * 将类别父子相认 转为 CategoryIndexVO
     *
     * @param categoryIndexDOS 数据库中的数据
     * @return CategoryIndexVO[]
     */
    private List<CategoryIndexVO> categoryDOTreeToVO(List<CategoryIndexDO> categoryIndexDOS) {
        log.debug("数据库的类别数据为：【{}】\n准备 把第一、二层存到 map 中", categoryIndexDOS);
        final String HREF_FIX = "category_";
        Map<Long, CategoryIndexVO> categoryIndexVOMap = categoryIndexDOS.stream()
                .filter(e -> e.getDepth() != 3)
                .collect(Collectors.toMap(
                        CategoryIndexDO::getId,
                        e -> {
                            CategoryIndexVO categoryIndexVO = new CategoryIndexVO();
                            System.out.println("---" + e);
                            BeanUtils.copyProperties(e, categoryIndexVO);
                            System.out.println("===" + categoryIndexVO);
                            return categoryIndexVO.
                                    setChildCategory(new ArrayList<>())
                                    .setHref(HREF_FIX + categoryIndexVO.getId());
                        },
                        (a, b) -> a.getId() > b.getId() ? b : a
                ));
        // 把第三层放到第二层的子集
        log.debug("准备把第三层放到第二层的子集：【{}】", categoryIndexVOMap);
        categoryIndexDOS.stream().filter(e -> e.getDepth() == 3)
                .forEach(e -> {
                    System.out.println(e);
                    CategoryIndexVO categoryIndexVO = new CategoryIndexVO();
                    BeanUtils.copyProperties(e, categoryIndexVO);
                    categoryIndexVO.setHref(HREF_FIX + categoryIndexVO.getId());
                    categoryIndexVO.setChildCategory(new ArrayList<>());
                    categoryIndexVOMap.get(e.getParentId())
                            .getChildCategory()
                            .add(categoryIndexVO);
                });
        // 把第二层放到第一层的子集
        log.debug("准备把第二层放到第一层的子集：【{}】", categoryIndexVOMap);
        categoryIndexVOMap.values().stream()
                .filter(e -> e.getDepth() == 2)
                .forEach(e -> categoryIndexVOMap.get(e.getParentId())
                        .getChildCategory().add(e));
        log.debug("一二层类别数量：" + categoryIndexVOMap.size());
        List<Long> ids = categoryIndexVOMap.values().stream()
                .filter(e -> e.getDepth() != 1)
                .map(CategoryIndexVO::getId)
                .collect(Collectors.toList());
        ids.forEach(categoryIndexVOMap.keySet()::remove);
        log.debug("一层类别数量：【{}】", categoryIndexVOMap.size());
        return new ArrayList<>(categoryIndexVOMap.values());
    }
}




